package com.mlh.dp.old;

// 给定一个数组，它的第 i 个元素是一支给定的股票在第 i 天的价格。
// 设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。
// 注意：你不能同时参与多笔交易（你必须在再次购买前出售掉之前的股票）。
//
// 输入：prices = [3,3,5,0,0,3,1,4]
// 输出：6
// 解释：在第 4 天（股票价格 = 0）的时候买入，在第 6 天（股票价格 = 3）的时候卖出，这笔交易所能获得利润 = 3-0 = 3 。
// 随后，在第 7 天（股票价格 = 1）的时候买入，在第 8 天 （股票价格 = 4）的时候卖出，这笔交易所能获得利润 = 4-1 = 3 。


//未解出
//分析：当时没想到对2次交易的状态去做定义，还以为要设置一个3维数组来解决，对数组的状态定义并不合适，很难解决题目
//可以看到 两笔交易 其状态是有限的  因此可以去定义他处于各种情况的状态  然后再来得出状态转移公私
//因此 在做dp题目的时候  一定要思考清楚 数组表示的状态是什么  在解决问题中出现了那些状态  进而才能去思考这些状态是如何转移的
public class MaxProfit3 {
    public static void main(String[] args) {
        int[] prices={1,2,3,4,5};
        System.out.println(method1(prices));
    }

    public static int method1(int[]prices){
        //定义五种状态
        // 0：从未拥有股票
        // 1：持有第一次交易的股票
        // 2：不持有股票，完成了第一次交易
        // 3：持有第二次交易的股票
        // 4：不持有股票，完成了第2次交易
        int[][]dp=new int[prices.length][5];
        dp[0][1]=-prices[0];
        dp[0][3]=-prices[0];
        for(int i=1;i<prices.length;++i){
            dp[i][1]=Math.max(dp[i-1][0]-prices[i],dp[i-1][1]);
            dp[i][2]=Math.max(dp[i-1][1]+prices[i],dp[i-1][2]);
            dp[i][3]=Math.max(dp[i-1][2]-prices[i],dp[i-1][3]);
            dp[i][4]=Math.max(dp[i-1][3]+prices[i],dp[i-1][4]);
        }
        return Math.max(dp[prices.length-1][0],Math.max(dp[prices.length-1][4],dp[prices.length-1][2]));

    }

    //每种状态只会用到上一种状态，因此可以进行空间优化
    public static int method2(int[]prices){
        //定义五种状态
        // 0：从未拥有股票
        // 1：持有第一次交易的股票
        // 2：不持有股票，完成了第一次交易
        // 3：持有第二次交易的股票
        // 4：不持有股票，完成了第2次交易
        //定义五种状态代替数组
        int state0=0,state1=-prices[0],state2=0,state3=-prices[0],state4=0;
        for(int i=1;i<prices.length;++i){
            //为什么这里可以变成这样 state1更新完 马上可以用于state2
            // dp[i][1]=Math.max(dp[i-1][0]-prices[i],dp[i-1][1]);
            //如果dp[i][1]=dp[i-1][0]-prices[i]
            //dp[i][2]=Math.max(dp[i-1][0]-prices[i]+prices[i],dp[i][2]) 这个表达式意味着他在i这天 又买有卖 相当于刷了一次交易  并不会影响最终的结果
            //如果dp[i][1]=dp[i-1][1]
            // dp[i][2]=Math.max(dp[i-1][1]+prices[i],dp[i-1][2]); 这个就是原来的表达式
            state1=Math.max(state0-prices[i],state1);
            state2=Math.max(state1+prices[i],state2);
            state3=Math.max(state2-prices[i],state3);
            state4=Math.max(state3+prices[i],state4);
        }
        return Math.max(state4,state2);
    }
}
